In [1]:
%load_ext autoreload
%autoreload 2
In [2]:
import numpy as np
from openfisca_core.model_api import *
from openfisca_senegal import SenegalTaxBenefitSystem
from openfisca_senegal.entities import Individu
In [3]:
tax_benefit_system = SenegalTaxBenefitSystem()
Les paramètres de la législation sont définis ci-dessous via une string XML.
Le barème de l'impôt progressif a été récupéré dans le fichier http://www.gouv.sn/IMG/pdf/cgi2013.pdf à la page 71.
In [4]:
tax_benefit_system.add_legislation_params(u'''
<NODE code="root">
<BAREME code="bareme_impot_progressif" type="monetary">
<TRANCHE code="tranche0">
<SEUIL>
<VALUE deb="2013-01-01" valeur="0" />
</SEUIL>
<TAUX>
<VALUE deb="2013-01-01" valeur="0" />
</TAUX>
</TRANCHE>
<TRANCHE code="tranche1">
<SEUIL>
<VALUE deb="2013-01-01" valeur="630000" />
</SEUIL>
<TAUX>
<VALUE deb="2013-01-01" valeur="0.2" />
</TAUX>
</TRANCHE>
<TRANCHE code="tranche2">
<SEUIL>
<VALUE deb="2013-01-01" valeur="1500000" />
</SEUIL>
<TAUX>
<VALUE deb="2013-01-01" valeur="0.3" />
</TAUX>
</TRANCHE>
<TRANCHE code="tranche3">
<SEUIL>
<VALUE deb="2013-01-01" valeur="4000000" />
</SEUIL>
<TAUX>
<VALUE deb="2013-01-01" valeur="0.35" />
</TAUX>
</TRANCHE>
<TRANCHE code="tranche4">
<SEUIL>
<VALUE deb="2013-01-01" valeur="8000000" />
</SEUIL>
<TAUX>
<VALUE deb="2013-01-01" valeur="0.37" />
</TAUX>
</TRANCHE>
<TRANCHE code="tranche5">
<SEUIL>
<VALUE deb="2013-01-01" valeur="13500000" />
</SEUIL>
<TAUX>
<VALUE deb="2013-01-01" valeur="0.4" />
</TAUX>
</TRANCHE>
</BAREME>
<NODE code="reductions_pour_charge_de_famille">
<CODE code="taux_1" format="percent">
<VALUE deb="2013-01-01" valeur="0" />
</CODE>
<CODE code="taux_2" format="percent">
<VALUE deb="2013-01-01" valeur="0.1" />
</CODE>
<CODE code="taux_3" format="percent">
<VALUE deb="2013-01-01" valeur="0.15" />
</CODE>
<CODE code="taux_4" format="percent">
<VALUE deb="2013-01-01" valeur="0.2" />
</CODE>
<CODE code="taux_5" format="percent">
<VALUE deb="2013-01-01" valeur="0.25" />
</CODE>
<CODE code="taux_6" format="percent">
<VALUE deb="2013-01-01" valeur="0.3" />
</CODE>
<CODE code="taux_7" format="percent">
<VALUE deb="2013-01-01" valeur="0.35" />
</CODE>
<CODE code="taux_8" format="percent">
<VALUE deb="2013-01-01" valeur="0.4" />
</CODE>
<CODE code="taux_9" format="percent">
<VALUE deb="2013-01-01" valeur="0.45" />
</CODE>
<CODE code="min_1" type="monetary">
<VALUE deb="2013-01-01" valeur="0" />
</CODE>
<CODE code="min_2" type="monetary">
<VALUE deb="2013-01-01" valeur="100000" />
</CODE>
<CODE code="min_3" type="monetary">
<VALUE deb="2013-01-01" valeur="200000" />
</CODE>
<CODE code="min_4" type="monetary">
<VALUE deb="2013-01-01" valeur="300000" />
</CODE>
<CODE code="min_5" type="monetary">
<VALUE deb="2013-01-01" valeur="400000" />
</CODE>
<CODE code="min_6" type="monetary">
<VALUE deb="2013-01-01" valeur="500000" />
</CODE>
<CODE code="min_7" type="monetary">
<VALUE deb="2013-01-01" valeur="600000" />
</CODE>
<CODE code="min_8" type="monetary">
<VALUE deb="2013-01-01" valeur="700000" />
</CODE>
<CODE code="min_9" type="monetary">
<VALUE deb="2013-01-01" valeur="800000" />
</CODE>
<CODE code="max_1" type="monetary">
<VALUE deb="2013-01-01" valeur="0" />
</CODE>
<CODE code="max_2" type="monetary">
<VALUE deb="2013-01-01" valeur="300000" />
</CODE>
<CODE code="max_3" type="monetary">
<VALUE deb="2013-01-01" valeur="650000" />
</CODE>
<CODE code="max_4" type="monetary">
<VALUE deb="2013-01-01" valeur="1100000" />
</CODE>
<CODE code="max_5" type="monetary">
<VALUE deb="2013-01-01" valeur="1650000" />
</CODE>
<CODE code="max_6" type="monetary">
<VALUE deb="2013-01-01" valeur="2030000" />
</CODE>
<CODE code="max_7" type="monetary">
<VALUE deb="2013-01-01" valeur="2490000" />
</CODE>
<CODE code="max_8" type="monetary">
<VALUE deb="2013-01-01" valeur="2755000" />
</CODE>
<CODE code="max_9" type="monetary">
<VALUE deb="2013-01-01" valeur="3180000" />
</CODE>
</NODE>
</NODE>
''')
In [ ]:
class date_de_naissance(Variable):
value_type = date
definition_period = ETERNITY
entity = Individu
label = u"Date de naissance"
tax_benefit_system.update_variable(date_de_naissance)
class salaire(Variable):
value_type = float
definition_period = YEAR
entity = Individu
label = "Salaire"
set_input = set_input_divide_by_period
tax_benefit_system.update_variable(salaire)
In [ ]:
class est_marie(Variable):
value_type = bool
definition_period = YEAR
entity = Individu
label = u"Est marié"
set_input = set_input_dispatch_by_period
tax_benefit_system.update_variable(est_marie)
class conjoint_a_des_revenus(Variable):
value_type = bool
definition_period = YEAR
entity = Individu
tax_benefit_system.update_variable(conjoint_a_des_revenus)
class nombre_enfants(Variable):
value_type = int
definition_period = YEAR
entity = Individu
tax_benefit_system.update_variable(nombre_enfants)
In [ ]:
class nombre_de_parts(Variable):
value_type = float
definition_period = YEAR
entity = Individu
label = u"Nombre de parts"
def formula(individu, period):
nombre_de_parts_enfants = individu('nombre_enfants', period) * 0.5
conjoint_a_des_revenus = individu('conjoint_a_des_revenus', period)
est_marie = individu('est_marie', period)
nombre_de_parts_conjoint = est_marie * 0.5 + (1 - conjoint_a_des_revenus) * 0.5
nombre_de_parts = 1 + nombre_de_parts_conjoint + nombre_de_parts_enfants
return np.minimum(5, nombre_de_parts)
tax_benefit_system.update_variable(nombre_de_parts)
class impot_avant_reduction_famille(Variable):
value_type = float
definition_period = YEAR
entity = Individu
def formula(individu, period, legislation):
salaire = individu('salaire', period, options = [ADD])
bareme_impot_progressif = legislation(period).bareme_impot_progressif
return bareme_impot_progressif.calc(salaire)
tax_benefit_system.update_variable(impot_avant_reduction_famille)
class reduction_impots_pour_charge_famille(Variable):
value_type = float
definition_period = YEAR
entity = Individu
def formula(individu, period, legislation):
impot_avant_reduction_famille = individu('impot_avant_reduction_famille', period)
nombre_de_parts = individu('nombre_de_parts', period)
reductions_pour_charge_de_famille = legislation(period).reductions_pour_charge_de_famille
taux = (nombre_de_parts == 1) * reductions_pour_charge_de_famille.taux_1 + \
(nombre_de_parts == 1.5) * reductions_pour_charge_de_famille.taux_2 + \
(nombre_de_parts == 2) * reductions_pour_charge_de_famille.taux_3 + \
(nombre_de_parts == 2.5) * reductions_pour_charge_de_famille.taux_4 + \
(nombre_de_parts == 3) * reductions_pour_charge_de_famille.taux_5 + \
(nombre_de_parts == 3.5) * reductions_pour_charge_de_famille.taux_6 + \
(nombre_de_parts == 4) * reductions_pour_charge_de_famille.taux_7 + \
(nombre_de_parts == 4.5) * reductions_pour_charge_de_famille.taux_8 + \
(nombre_de_parts == 5) * reductions_pour_charge_de_famille.taux_9
minimum = (nombre_de_parts == 1) * reductions_pour_charge_de_famille.min_1 + \
(nombre_de_parts == 1.5) * reductions_pour_charge_de_famille.min_2 + \
(nombre_de_parts == 2) * reductions_pour_charge_de_famille.min_3 + \
(nombre_de_parts == 2.5) * reductions_pour_charge_de_famille.min_4 + \
(nombre_de_parts == 3) * reductions_pour_charge_de_famille.min_5 + \
(nombre_de_parts == 3.5) * reductions_pour_charge_de_famille.min_6 + \
(nombre_de_parts == 4) * reductions_pour_charge_de_famille.min_7 + \
(nombre_de_parts == 4.5) * reductions_pour_charge_de_famille.min_8 + \
(nombre_de_parts == 5) * reductions_pour_charge_de_famille.min_9
maximum = (nombre_de_parts == 1) * reductions_pour_charge_de_famille.max_1 + \
(nombre_de_parts == 1.5) * reductions_pour_charge_de_famille.max_2 + \
(nombre_de_parts == 2) * reductions_pour_charge_de_famille.max_3 + \
(nombre_de_parts == 2.5) * reductions_pour_charge_de_famille.max_4 + \
(nombre_de_parts == 3) * reductions_pour_charge_de_famille.max_5 + \
(nombre_de_parts == 3.5) * reductions_pour_charge_de_famille.max_6 + \
(nombre_de_parts == 4) * reductions_pour_charge_de_famille.max_7 + \
(nombre_de_parts == 4.5) * reductions_pour_charge_de_famille.max_8 + \
(nombre_de_parts == 5) * reductions_pour_charge_de_famille.max_9
reduction_impot = np.clip(impot_avant_reduction_famille * taux, a_min=minimum, a_max=maximum)
return reduction_impot
tax_benefit_system.update_variable(reduction_impots_pour_charge_famille)
class impot_revenus(Variable):
value_type = float
definition_period = YEAR
entity = Individu
def formula(individu, period):
impot_avant_reduction_famille = individu('impot_avant_reduction_famille', period)
reduction_impots_pour_charge_famille = individu('reduction_impots_pour_charge_famille', period)
impot_apres_reduction_famille = impot_avant_reduction_famille - reduction_impots_pour_charge_famille
return np.maximum(0, impot_apres_reduction_famille)
tax_benefit_system.update_variable(impot_revenus)
In [ ]:
scenario = tax_benefit_system.new_scenario()
In [ ]:
scenario.init_single_entity(
parent1={
'salaire': 1800000,
'est_marie': True,
'conjoint_a_des_revenus': False,
'nombre_enfants': 2,
},
period='2015',
)
In [ ]:
simulation = scenario.new_simulation()
In [ ]:
simulation.individu('salaire', period='2015')
In [ ]:
simulation.individu('impot_avant_reduction_famille', period='2015')
In [ ]:
simulation.individu('reduction_impots_pour_charge_famille', period='2015')
In [ ]:
simulation.individu('impot_revenus', period='2015')
In [ ]:
(1500000 - 630000) * 0.2 + (1800000 - 1500000) * 0.3
In [ ]:
simulation.individu('nombre_de_parts', period='2015')
In [ ]:
import matplotlib.pyplot as plt
%matplotlib inline
In [ ]:
scenario1 = tax_benefit_system.new_scenario()
scenario1.init_single_entity(
parent1={
'est_marie': True,
'conjoint_a_des_revenus': False,
'nombre_enfants': 0,
},
period='2015',
axes=[
{
'count': 100,
'min': 0,
'max': 15e6,
'name': 'salaire',
}
],
)
simulation1 = scenario1.new_simulation()
salaire1 = simulation1.individu('salaire', period='2015')
reduction_impots_pour_charge_famille1 = simulation1.individu('reduction_impots_pour_charge_famille', period='2015')
impot_avant_reduction_famille1 = simulation1.individu('impot_avant_reduction_famille', period='2015')
impot_revenus1 = simulation1.individu('impot_revenus', period='2015')
In [ ]:
plt.figure(figsize=(12, 8))
plt.plot(salaire1, impot_avant_reduction_famille1, label=u'avant réduction famille')
plt.plot(salaire1, reduction_impots_pour_charge_famille1, label=u'réduction famille')
plt.plot(salaire1, impot_revenus1, label=u'impôt revenus')
plt.xlabel(u'Salaire')
plt.legend()
plt.title(u'0 enfants', fontsize=20)
In [ ]:
scenario2 = tax_benefit_system.new_scenario()
scenario2.init_single_entity(
parent1={
'est_marie': True,
'conjoint_a_des_revenus': False,
'nombre_enfants': 1,
},
period='2015',
axes=[
{
'count': 100,
'min': 0,
'max': 15e6,
'name': 'salaire',
}
],
)
simulation2 = scenario2.new_simulation()
salaire2 = simulation2.individu('salaire', period='2015')
reduction_impots_pour_charge_famille2 = simulation2.individu('reduction_impots_pour_charge_famille', period='2015')
impot_avant_reduction_famille2 = simulation2.individu('impot_avant_reduction_famille', period='2015')
impot_revenus2 = simulation2.individu('impot_revenus', period='2015')
In [ ]:
plt.figure(figsize=(12, 8))
plt.plot(salaire2, impot_avant_reduction_famille2, label=u'avant réduction famille')
plt.plot(salaire2, reduction_impots_pour_charge_famille2, label=u'réduction famille')
plt.plot(salaire2, impot_revenus2, label=u'impôt revenus')
plt.xlabel(u'Salaire')
plt.legend()
plt.title(u'1 enfant', fontsize=20)
In [ ]:
impot_revenus_diff = np.abs(impot_revenus2 - impot_revenus1)
plt.figure(figsize=(12, 8))
plt.plot(salaire1, impot_revenus_diff, label=u'Différence d\'impôt revenus')
plt.xlabel(u'Salaire')
plt.legend()
plt.title(u'Gain fiscal du 1er enfant', fontsize=20)
plot_margin = 10000
x0, x1, y0, y1 = plt.axis()
plt.axis((x0 - plot_margin, x1 + plot_margin, y0 - plot_margin, y1 + plot_margin))
In [ ]:
from openfisca_core import rates
In [ ]:
fig, ax1 = plt.subplots(figsize=(12, 8))
ax1.plot(salaire1, impot_revenus1)
ax1.set_xlabel(u'Salaire')
ax1.set_ylabel(u'Impôt sur les revenus')
ax2 = ax1.twinx()
ax2.set_ylabel(u'Taux marginaux')
ax2.plot(
salaire1[:-1],
1 - rates.marginal_rate(target=impot_revenus1, varying=salaire1),
)
In [ ]: